import type { SysConfigItem } from '../global.ts';

export const request = async (options: {
  url: string;
  method?: string;
  data?: any;
  success: (result: any) => void;
  fail?: (error: any) => void;
}) => {
  const { url, method, data, success, fail } = options;

  try {
    const response = await fetch(url, {
      method: method || "GET",
      headers: {
        "Content-Type": "application/json",
      },
      body: method === "POST" || method === "PUT" ? JSON.stringify(data) : null,
    });

    if (!response.ok) {
      throw new Error(`Network response was not ok ${response.statusText}`);
    }

    const result = await response.json();
    success(result);
  } catch (error) {
    console.error("There has been a problem with your fetch operation:", error);
    if (fail) {
      fail(error);
    }
  }
};

export const navigate = (path: string) => {
  window.location.hash = path;
};

// 获取tokenKey
export const getTokenKey = () => {
  return "token";
};

// 记录到loaclStorage
export const setLocalStorage = (key: string, value: any) => {
  if (typeof value === "object") {
    value = JSON.stringify(value);
  }
  window.localStorage.setItem(key, value);
};

// 从loaclStorage获取
export const getLocalStorage = (key: string) => {
  const value = window.localStorage.getItem(key);
  try {
    return JSON.parse(value!);
  } catch (error) {
    return value;
  }
};

export const findNodeByKey: any = (key: string, tree: any[]) => {
  for (let i = 0; i < tree.length; i++) {
    if (tree[i].key === key) {
      return tree[i];
    }
    if (tree[i].children) {
      let result = findNodeByKey(key, tree[i].children);
      if (result) {
        return result;
      }
    }
  }
  return null;
};

export const randomString = (length: number = 32): string => {
  const characters = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
  const charactersLength = characters.length;
  let result = "";

  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }

  return result;
};

export const hasHttpOrHttps = function (url?: string) {
  if (!url || typeof url !== "string") return false;
  return url.startsWith("http://") || url.startsWith("https://");
};

/**
 * 从系统配置中获取标签值
 * @param configKey - 配置键名(如:'设备分类','资产状态'等)
 * @param val - 需要转换的值
 * @param sysConfig - 系统配置对象
 * @returns 对应的标签值,如果未找到则返回原值
 */
export const getSysConfigLabel = (
  configKey: string,
  val: string | number,
  sysConfig: Record<string, SysConfigItem[]>
): string | number => {
  return (sysConfig[configKey] as SysConfigItem[])?.find(
    (item: SysConfigItem) => item.value === val
  )?.label ?? val;
};

/**
 * 路径匹配函数，用于检查给定路径是否匹配指定的模式
 * 支持路径参数，例如: /users/:id/profile
 * 
 * @param pattern - 路由模式，如: "/users/:id/profile"
 * @param path - 实际路径，如: "/users/123/profile"
 * @param extractParams - 是否提取参数到返回值中，默认为false
 * @returns 如果extractParams为false，返回布尔值表示是否匹配；如果为true，返回匹配结果对象{matched: boolean, params: Record<string, string>}
 */
export const matchPath = (
  pattern: string, 
  path: string, 
  extractParams: boolean = false
): boolean | { matched: boolean; params: Record<string, string> } => {
  const patternParts = pattern.split('/').filter(Boolean);
  const pathParts = path.split('/').filter(Boolean);
  
  // 如果路径段数不匹配，则直接返回false
  if (patternParts.length !== pathParts.length) {
    return extractParams ? { matched: false, params: {} } : false;
  }
  
  const params: Record<string, string> = {};
  let matched = true;
  
  for (let i = 0; i < patternParts.length; i++) {
    // 如果是参数部分（以 : 开头）
    if (patternParts[i].startsWith(':')) {
      // 提取参数名和值
      const paramName = patternParts[i].substring(1);
      params[paramName] = pathParts[i];
      continue;
    }
    
    // 否则必须精确匹配
    if (patternParts[i] !== pathParts[i]) {
      matched = false;
      break;
    }
  }
  
  // 根据extractParams参数决定返回值类型
  return extractParams ? { matched, params } : matched;
};

/**
 * 从URL中提取参数
 * 
 * @param pattern - 路由模式，如: "/users/:id/profile"
 * @param path - 实际路径，如: "/users/123/profile"
 * @returns 提取的参数对象
 */
export const extractParamsFromPath = (pattern: string, path: string): Record<string, string> => {
  const result = matchPath(pattern, path, true) as { matched: boolean; params: Record<string, string> };
  
  // 如果路径不匹配，返回空对象
  if (!result.matched) {
    return {};
  }
  
  return result.params;
};

/**
 * 查找匹配的路由模式
 * 
 * @param patterns - 路由模式数组
 * @param path - 实际路径
 * @returns 匹配的模式，如果没有找到则返回null
 */
export const findMatchingPattern = (patterns: string[], path: string): string | null => {
  for (const pattern of patterns) {
    if (matchPath(pattern, path)) {
      return pattern;
    }
  }
  return null;
};

/**
 * 拼接 host 和 src
 * @param host - 主机地址
 * @param src - 资源路径
 * @returns 拼接后的完整路径
 */
export const concatHost = (host: string, src: string) => {
  // 如果 host 为空，则直接返回 src
  if (!host) return src;

  // 如果 src 已经包含 http 或 https，则直接返回 src
  if( hasHttpOrHttps(src)) return src;

  // 如果 host 以 / 结尾，则直接拼接 src
  if (host.endsWith('/')) {
    return `${host}${src}`;
  }

  // 否则，拼接 src
  return `${host}/${src}`;
}

/**
 * 使用 history API 进行导航并触发 popstate 事件
 * @param path - 要导航到的路径
 * @param target - 导航目标窗口，可选值为 'top' | 'self'，默认为 'self'
 */
export const pushStateAndTrigger = (path: string, target: 'top' | 'self' = 'self') => {
  const targetWindow = target === 'top' ? window.top : window;
  if (!targetWindow) return;
  
  targetWindow.history.pushState({}, '', path);
  // 触发 popstate 事件以更新内容
  targetWindow.dispatchEvent(new PopStateEvent('popstate', { state: {} }));
};